﻿using System;
using System.Collections.Generic;
using System.Linq;
using Sustainalytics.Utils;
using Sustainalytics.Utils.WebApi.ErrorCodes;
using Sustainalytics.Entities;
using System.Web.Http;
using Sustainalytics.FTPReport.BusinessLogic;
using System.Net.Http;
using System.Net;
using System.Web.Http.Cors;
using Sustainalytics.Utils.Serilog;

namespace Sustainalytics.FTPReports.Service
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/v1/ftpclientreport")]
    public class FtpReportInfoController : ApiController, IFtpReportInfoController
    {
        IReportsFtpManagement businessLogicReportsFtp;

        public FtpReportInfoController()
        {
            try
            {
                CommonEventSerilog.Log.InitController();

                businessLogicReportsFtp = new ReportsFtpManagement();

                CommonEventSerilog.Log.InitControllerSuccess();
            }
            catch (Exception ex)
            {
                CommonEventSerilog.Log.InitControllerError(ex);
            }
        }

        public FtpReportInfoController(IReportsFtpManagement reportsFtpManager)
        {
            try
            {
                CommonEventSerilog.Log.InitController();

                businessLogicReportsFtp = reportsFtpManager;

                CommonEventSerilog.Log.InitControllerSuccess();
            }
            catch (Exception ex)
            {
                CommonEventSerilog.Log.InitControllerError(ex);
            }

        }

        [Route("account/{accountId}")]
        [HttpGet]
        public HttpResponseMessage Get(Guid accountId)
        {
            try
            {
                if (accountId == null)
                {
                    return Request.CreateResponse(HttpStatusCode.BadRequest,
                    new { ErrorStatusCode = WebAPIGeneralErrorCodes.OperationNotAllowed });
                }

                List<FtpClientReport> ftpClientReportData = businessLogicReportsFtp.LoadFtpClientReportsForAccount(accountId);
                if (ftpClientReportData.Any())
                {
                    List<FtpClientReportDto> ftpClientReportsDtos =
                        ftpClientReportData.Select(clientFtpReportItem => FtpClientReportDto.ToFtpClientReportDto(clientFtpReportItem)).ToList();

                    return Request.CreateResponse(HttpStatusCode.OK, ftpClientReportsDtos);
                }

                return Request.CreateResponse(HttpStatusCode.NoContent);
            }
            catch (FtpReportCriticalPropertiesMissingException)
            {

                return this.Request.CreateResponse(HttpStatusCode.BadRequest,
                    new { ErrorStatusCode = WebAPIGeneralErrorCodes.InputIsNull });
            }
            catch (Exception)
            {

                return this.Request.CreateResponse(HttpStatusCode.InternalServerError,
                    new { ErrorStatusCode = WebAPIGeneralErrorCodes.UnhandledException });
            }

        }


        [Route("")]
        [HttpPost]
        public HttpResponseMessage Post([FromBody] FtpClientReportDto ftpClientReportDto)
        {
            try
            {
                if (ftpClientReportDto == null)
                {
                    var ftpEx = new FtpReportDataObjectMissingException("FTP Client Report data object is null.");
                    return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing });
                }

                businessLogicReportsFtp.AddFtpClientReport(ftpClientReportDto);

                return Request.CreateResponse(HttpStatusCode.OK);

            }
            catch (FtpClientReportMandatoryDataMissingException clEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = clEx.Message
                    });
            }
            catch (FtpReportCriticalPropertiesMissingException ex)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ex.Message
                    });
            }
            catch (FtpReportDataObjectMissingException ftpEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ftpEx.Message
                    });
            }
            catch (Exception normalEx)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.UnhandledException });
            }
        }

        [Route("")]
        [HttpPut]
        public HttpResponseMessage Put([FromBody] FtpClientReportDto ftpClientReportDto)
        {
            try
            {
                if (ftpClientReportDto == null)
                {
                    var ftpEx = new FtpReportDataObjectMissingException("FTP Client Report data object is null.");
                    return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing });
                }

                businessLogicReportsFtp.ModifyFtpClientReport(ftpClientReportDto);
                return Request.CreateResponse(HttpStatusCode.OK);

            }
            catch (FtpReportInvalidOperationException clEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.ResourceNotFound,
                        message = clEx.Message
                    });
            }
            catch (FtpClientReportMandatoryDataMissingException clEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = clEx.Message
                    });
            }
            catch (FtpReportCriticalPropertiesMissingException ex)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ex.Message
                    });
            }
            catch (FtpReportDataObjectMissingException ftpEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ftpEx.Message
                    });
            }
            catch (Exception normalEx)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.UnhandledException });
            }
        }

        [Route("account/{accountId}/reportId/{clientReportId}")]
        [HttpDelete]
        public HttpResponseMessage Delete(Guid accountId, Guid clientReportId)
        {
            try
            {
                if (accountId == null || clientReportId == null)
                {
                    var ftpEx = new FtpReportCriticalPropertiesMissingException("Missing critical property of Client FTP Report. FTP Report Account Id is: " + accountId + ",Client Report Id is: " + clientReportId);
                    return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing });
                }

                businessLogicReportsFtp.DeleteFtpClientReport(accountId, clientReportId);

                return Request.CreateResponse(HttpStatusCode.OK);

            }
            catch (FtpReportInvalidOperationException clEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.ResourceNotFound,
                        message = clEx.Message
                    });
            }
            catch (FtpClientReportMandatoryDataMissingException clEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = clEx.Message
                    });
            }
            catch (FtpReportCriticalPropertiesMissingException ex)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ex.Message
                    });
            }
            catch (FtpReportDataObjectMissingException ftpEx)
            {
                return Request.CreateResponse(HttpStatusCode.MethodNotAllowed,
                    new
                    {
                        ErrorStatusCode = WebAPIGeneralErrorCodes.InputContentDataMissing,
                        message = ftpEx.Message
                    });
            }
            catch (Exception normalEx)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError,
                                            new { ErrorStatusCode = WebAPIGeneralErrorCodes.UnhandledException });
            }
        }
    }
}
